home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 019a / tde10src.zip / WINDOW.C < prev   
C/C++ Source or Header  |  1991-06-05  |  25KB  |  832 lines

  1. /*******************  start of original comments  ********************/
  2. /*
  3.  * Written by Douglas Thomson (1989/1990)
  4.  *
  5.  * This source code is released into the public domain.
  6.  */
  7.  
  8. /*
  9.  * Name:    dte - Doug's Text Editor program - window module
  10.  * Purpose: This file contains the code associated with opening and sizing
  11.  *           windows, and also displaying the help window.
  12.  * File:    window.c
  13.  * Author:  Douglas Thomson
  14.  * System:  this file is intended to be system-independent
  15.  * Date:    October 12, 1989
  16.  */
  17. /*********************  end of original comments   ********************/
  18.  
  19.  
  20. /*
  21.  * The window routines have been EXTENSIVELY rewritten.  Some routines were
  22.  * changed so only one logical function is carried out, eg. 'initialize_window'.
  23.  * I like the Microsoft way of resizing windows - just press the up and down
  24.  * arrows to adjust the window to desired size.  I also like pressing one key
  25.  * to change windows.  All of which are implemented.
  26.  *
  27.  * New editor name:  tde, the Thomson-Davis Editor.
  28.  * Author:           Frank Davis
  29.  * Date:             June 5, 1991
  30.  *
  31.  * This modification of Douglas Thomson's code is released into the
  32.  * public domain, Frank Davis.  You may distribute it freely.
  33.  */
  34.  
  35. #include "tdestr.h"
  36. #include "common.h"
  37. #include "define.h"
  38. #include "funcdef.h"
  39. #include "tdefunc.h"
  40. #if defined( __MSC__ )
  41.    #include <sys/types.h>
  42.    #include <sys/stat.h>
  43. #endif
  44.  
  45.  
  46. /*
  47.  * Name:    initialize_window
  48.  * Purpose: To open a new window
  49.  * Date:    June 5, 1991
  50.  * Returns: OK if window opened successfully
  51.  *          ERROR if anything went wrong
  52.  * Notes:   If this is first window then set up as normal displayed window
  53.  *          otherwise make the present window invisible and open a new
  54.  *          window in the same screen location as the old one.
  55.  */
  56. int  initialize_window( )
  57. {
  58. int top;
  59. int bottom;
  60. windows *wp;        /* used for scanning windows */
  61. windows *window;
  62. file_infos *fp;     /* used for scanning files */
  63. int rc;
  64.  
  65.    rc = OK;
  66.    window = g_status.current_window;
  67.    fp = g_status.current_file;
  68.    if (window == NULL) {
  69.       /*
  70.        * special case if this is the first window on screen.
  71.        */
  72.       top = 0;
  73.       bottom = g_display.nlines;
  74.    } else {
  75.       /*
  76.        * else put the new window in same place as current window.
  77.        * make current window invisible.  new window becomes current window.
  78.        */
  79.       top = window->top_line - 1;
  80.       bottom = window->bottom_line;
  81.    }
  82.  
  83.    if (create_window( &wp, top, bottom, fp ) == ERROR) {
  84.       error( WARNING, bottom, "out of memory" );
  85.  
  86.       /*
  87.        * This is a real nuisance. We had room for the file and the
  88.        *  file structure, but not enough for the window as well.
  89.        * Now we must free all the memory that has already been
  90.        *  allocated.
  91.        */
  92.       if (fp->ref_count == 0) {
  93.          if (fp->prev)
  94.             fp->prev->next = fp->next;
  95.          else
  96.             g_status.file_list = fp->next;
  97.          if (fp->next)
  98.             fp->next->prev = fp->prev;
  99.          g_status.end_mem = fp->start_text;
  100.          free( fp );
  101.       }
  102.       rc = ERROR;
  103.    }
  104.  
  105.    if (rc != ERROR) {
  106.       /*
  107.        * set up the new cursor position as appropriate
  108.        */
  109.       wp->cursor = fp->start_text;
  110.       wp->cursor = cpf( wp->cursor );
  111.       wp->ccol = 0;
  112.       wp->rcol = 0;
  113.       wp->bcol = 0;
  114.       wp->rline = 1l;
  115.       wp->visible = TRUE;
  116.       if (window != NULL)
  117.          window->visible = FALSE;
  118.  
  119.       /*
  120.        * the new window becomes the current window.
  121.        */
  122.       g_status.current_window = wp;
  123.    }
  124.    return( rc );
  125. }
  126.  
  127.  
  128. /*
  129.  * Name:    next_window
  130.  * Purpose: To select an existing window.
  131.  * Date:    June 5, 1991
  132.  * Passed:  window:   information allowing access to the current window
  133.  * Notes:   Start with current window.  If next window exits then go to
  134.  *          it else go to the first (top) window on screen.
  135.  */
  136. void next_window( window )
  137. windows *window;
  138. {
  139. int change;
  140. windows *wp;
  141.  
  142.  
  143.    if (window != NULL) {
  144.       change = FALSE;
  145.       wp = window;
  146.       if (wp->next != NULL) {
  147.          wp = wp->next;
  148.          while (wp != NULL && wp->top_line-2 != window->bottom_line ||
  149.                 !wp->visible)
  150.             wp = wp->next;
  151.          if (wp != NULL && wp->visible)
  152.             change = TRUE;
  153.       }
  154.       if (change != TRUE) {
  155.          wp = window;
  156.          while (wp->prev != NULL)
  157.             wp = wp->prev;
  158.          while (wp != NULL && wp->top_line != 1 || !wp->visible)
  159.             wp = wp->next;
  160.          if (wp != NULL && wp != window && wp->visible)
  161.             change = TRUE;
  162.       }
  163.  
  164.       if (change == TRUE) {
  165.          g_status.current_window = wp;
  166.          g_status.current_file = wp->file_info;
  167.       }
  168.    }
  169. }
  170.  
  171.  
  172. /*
  173.  * Name:    prev_window
  174.  * Purpose: To select an existing window.
  175.  * Date:    June 5, 1991
  176.  * Passed:  window:   information allowing access to the current window
  177.  * Notes:   Start with current window.  If previous window exits then go to
  178.  *          it else go to the last (bottom) window on screen.  Opposite of
  179.  *          next_window.
  180.  */
  181. void prev_window( window )
  182. windows *window;
  183. {
  184. int change;
  185. windows *wp;
  186.  
  187.    if (window != NULL) {
  188.       change = FALSE;
  189.       wp = window;
  190.       if (wp->prev != NULL) {
  191.          wp = wp->prev;
  192.          while (wp != NULL && wp->bottom_line+2 != window->top_line ||
  193.                 !wp->visible)
  194.             wp = wp->prev;
  195.          if (wp != NULL && wp->visible)
  196.             change = TRUE;
  197.       }
  198.       if (change != TRUE) {
  199.          wp = window;
  200.          while (wp->next != NULL)
  201.             wp = wp->next;
  202.          while (wp != NULL && wp->bottom_line != g_display.nlines ||
  203.                !wp->visible)
  204.             wp = wp->prev;
  205.          if (wp != NULL && wp != window && wp->visible)
  206.             change = TRUE;
  207.       }
  208.  
  209.       if (change == TRUE) {
  210.          g_status.current_window = wp;
  211.          g_status.current_file = wp->file_info;
  212.       }
  213.    }
  214. }
  215.  
  216.  
  217. /*
  218.  * Name:    split_screen
  219.  * Purpose: To split screen.
  220.  * Date:    June 5, 1991
  221.  * Passed:  window:   information allowing access to the current window
  222.  * Notes:   split the screen at the cursor position.
  223.  */
  224. void split_screen( windows *window )
  225. {
  226. windows *wp;
  227. file_infos *file;   /* file structure for file belonging to new window */
  228. int prompt_line;
  229.  
  230.    prompt_line = window->bottom_line;
  231.    /*
  232.     * check that there is room for the window
  233.     */
  234.    if (window->bottom_line - window->cline < 2)
  235.       error( WARNING, prompt_line, "move cursor up first" );
  236.    else {
  237.       file = window->file_info;
  238.       if (create_window( &wp, window->cline+1, window->bottom_line,
  239.                          file ) == ERROR) {
  240.          error( WARNING, prompt_line, "out of memory" );
  241.       } else {
  242.          /*
  243.           * record that the current window has lost some lines from
  244.           *  the bottom for the new window, and adjust its page size
  245.           *  etc accordingly.
  246.           */
  247.          window->bottom_line = window->cline;
  248.          window->dirty = LOCAL;
  249.          setup_window( window );
  250.  
  251.          /*
  252.           * set up the new cursor position as appropriate
  253.           */
  254.          wp->rcol = window->rcol;
  255.          wp->ccol = window->ccol;
  256.          wp->bcol = window->bcol;
  257.          wp->rline = window->rline;
  258.          wp->cursor = window->cursor;
  259.          wp->visible = TRUE;
  260.  
  261.          /*
  262.           * the new window becomes the current window.
  263.           */
  264.          g_status.current_window = wp;
  265.  
  266.          show_window_header( wp->file_info->file_name, wp );
  267.          show_size_name( wp );
  268.          show_size( wp );
  269.          wp->dirty = LOCAL;
  270.  
  271.          /*
  272.           *  adjust any invisible windows
  273.           */
  274.          wp = g_status.window_list;
  275.          while (wp != NULL) {
  276.             if (wp != window ) {
  277.                if (wp->top_line == window->top_line) {
  278.                   wp->bottom_line = window->bottom_line;
  279.                   setup_window( wp );
  280.                   /*
  281.                    * reset cline to some place safe
  282.                    */
  283.                   wp->cline = wp->top_line;
  284.                }
  285.             }
  286.             wp = wp->next;
  287.          }
  288.       }
  289.    }
  290. }
  291.  
  292.  
  293. /*
  294.  * Name:    size_window
  295.  * Purpose: To change the size of the current and one other window.
  296.  * Date:    June 5, 1991
  297.  * Passed:  window:   information allowing access to the current window
  298.  * Notes:   Use the Up and Down arrow keys to make the current window
  299.  *          bigger or smaller.  The window above, if it exists, will
  300.  *          either grow or contract accordingly.
  301.  */
  302. void size_window( window )
  303. windows *window;
  304. {
  305. char line_buff[(MAX_COLS+1)*2]; /* buffer for char and attribute  */
  306. int func, c, above_change;
  307. windows *above, *n;
  308. text_ptr p;
  309. int prompt_line;
  310. int resize;
  311. char *file_name;
  312. char *instr =
  313.        "Press Up or Down to change window size.  Press Return when done.";
  314.  
  315.    if (window->top_line != 1) {
  316.       above_change = 0;
  317.       file_name = window->file_info->file_name;
  318.       prompt_line = window->bottom_line;
  319.       save_screen_line( 0, prompt_line, line_buff );
  320.       set_prompt( instr, prompt_line );
  321.  
  322.       /*
  323.        * resizing only affects current window and above visible window
  324.        */
  325.       above = g_status.window_list;
  326.       while (above->bottom_line + 2 != window->top_line || !above->visible)
  327.          above = above->next;
  328.       for (func=0; func != AbortCommand && func != Rturn; ) {
  329.          c = (c=getch()) != 0 ? c : getch() | 0x100;
  330.          func = key_func[c].func;
  331.          resize = FALSE;
  332.  
  333.          /*
  334.           * if line up make current window top line grow and bottom line
  335.           * of above window shrink.   if window movement covers up current
  336.           * line of window then we must adjust logical line and real line.
  337.           */
  338.          if (func == LineUp) {
  339.             if (above->bottom_line > above->top_line) {
  340.                if (window->rline == (window->cline - (window->top_line-1)))
  341.                   --window->cline;
  342.                --window->top_line;
  343.                if (above->cline == above->bottom_line) {
  344.                   above->cursor = cpb( above->cursor );
  345.                   above->cursor = find_prev( above->cursor );
  346.                   --above->rline;
  347.                   --above->cline;
  348.                   show_line_col( above );
  349.                   --above_change;
  350.                }
  351.                --above->bottom_line;
  352.                resize = TRUE;
  353.                display_current_window( window );
  354.                save_screen_line( 0, prompt_line, line_buff );
  355.             }
  356.  
  357.          /*
  358.           * if line down make current window top line shrink and bottom line
  359.           * of above window grow.   if window movement covers up current
  360.           * line of window then we must adjust logical line and real line.
  361.           */
  362.          } else if (func == LineDown) {
  363.             if (window->bottom_line > window->top_line) {
  364.                if (window->cline == window->top_line) {
  365.                   ++window->cline;
  366.                   window->cursor = cpf( window->cursor );
  367.                   p = find_next( window->cursor );
  368.                   if (p != NULL) {
  369.                      window->cursor = p;
  370.                      ++window->rline;
  371.                   }
  372.                }
  373.                ++window->top_line;
  374.                ++above->bottom_line;
  375.                ++above_change;
  376.                resize = TRUE;
  377.                display_current_window( above );
  378.             }
  379.          }
  380.  
  381.          /*
  382.           * if we resize a window then update window size and current and
  383.           * real lines if needed.
  384.           */
  385.          if (resize == TRUE) {
  386.             setup_window( window );
  387.             setup_window( above );
  388.             show_window_header( file_name, window );
  389.             show_size_name( window );
  390.             show_size( window );
  391.             show_line_col( window );
  392.             set_prompt( instr, prompt_line );
  393.          }
  394.       }
  395.       restore_screen_line( 0, prompt_line, line_buff );
  396.       if (above_change != 0) {
  397.          n = g_status.window_list;
  398.          while (n != NULL) {
  399.             /*
  400.              * check all invisible windows - make sure they have
  401.              * correct top and bottom lines.
  402.              */
  403.             if (n != above  &&  n != window ) {
  404.                if (n->top_line == above->top_line) {
  405.                   n->bottom_line = above->bottom_line;
  406.                   setup_window( n );
  407.                   if (n->cline > n->bottom_line)
  408.                      n->cline = n->bottom_line;
  409.                } else if (n->bottom_line == window->bottom_line) {
  410.                   n->top_line = window->top_line;
  411.                   setup_window( n );
  412.                   if (n->cline < n->top_line)
  413.                      n->cline = n->top_line;
  414.                }
  415.             }
  416.             n = n->next;
  417.          }
  418.       }
  419.    } else
  420.      error( WARNING, window->bottom_line, "can not resize top window" );
  421. }
  422.  
  423.  
  424. /*
  425.  * Name:    setup_window
  426.  * Purpose: To set the page length and the center line of a window, based
  427.  *           on the top and bottom lines.
  428.  * Date:    June 5, 1991
  429.  * Passed:  window: window to be set up
  430.  */
  431. void setup_window( window )
  432. windows *window;
  433. {
  434.    window->page = window->bottom_line - window->top_line -
  435.                   g_status.overlap + 1;
  436.    if (window->page < 1)
  437.       window->page = 1;
  438. }
  439.  
  440.  
  441. /*
  442.  * Name:    finish
  443.  * Purpose: To remove the current window, and terminate the program if no
  444.  *           more windows are left.
  445.  * Date:    June 5, 1991
  446.  * Passed:  window: information allowing access to the current window
  447.  *          stop:  set to TRUE if this is the last window in window list
  448.  * Notes:   Order of deciding which window becomes current window:
  449.  *          1) If any invisible windows with same top and bottom line then
  450.  *          first invisible one becomes current window.
  451.  *          2) first available invisible window becomes current window.
  452.  *          3) window above if it exists becomes current window
  453.  *          4) window below if it exists becomes current window
  454.  */
  455. void finish( window, stop )
  456. windows *window;
  457. int *stop;
  458. {
  459. windows *wp;        /* for scanning other windows */
  460. file_infos *file;   /* for scanning other files */
  461. long number;        /* number of bytes removed / copied */
  462. int poof;
  463. int cline;
  464. int top, bottom;
  465.  
  466.    /*
  467.     * remove old window from list
  468.     */
  469.    top = 1;
  470.    bottom = g_display.nlines;
  471.    if (window->prev == NULL) {
  472.       if (window->next == NULL)
  473.          *stop = TRUE;
  474.       else
  475.          g_status.window_list = window->next;
  476.    } else
  477.       window->prev->next = window->next;
  478.  
  479.  
  480.    /*
  481.     * remove all hidden windows that point to same file
  482.     */
  483.    if (*stop != TRUE) {
  484.       if (window->next)
  485.          window->next->prev = window->prev;
  486.       for (wp=g_status.window_list; wp != NULL; wp=wp->next) {
  487.          if (!wp->visible && wp->file_info == window->file_info) {
  488.             if (wp->prev == NULL) {
  489.                if (wp->next == NULL)
  490.                   *stop = TRUE;
  491.                else
  492.                   g_status.window_list = wp->next;
  493.             } else
  494.                wp->prev->next = wp->next;
  495.             if (wp->next)
  496.                wp->next->prev = wp->prev;
  497.             --wp->file_info->ref_count;
  498.             free( wp );
  499.          }
  500.       }
  501.    }
  502.  
  503.    if (*stop != TRUE) {
  504.       /*
  505.        * see if there are any invisible windows with same top and bottom
  506.        * lines as this window.
  507.        */
  508.       poof = FALSE;
  509.       wp = g_status.window_list;
  510.       while (wp != NULL && poof == FALSE) {
  511.          if (wp->top_line == window->top_line && !wp->visible) {
  512.             poof = TRUE;
  513.             top = window->top_line;
  514.             bottom = window->bottom_line;
  515.          } else
  516.             wp = wp->next;
  517.       }
  518.  
  519.       if (poof == FALSE) {
  520.          /*
  521.           * see if there are any other invisible windows
  522.           */
  523.          wp = g_status.window_list;
  524.          while (wp != NULL && poof == FALSE) {
  525.             if (!wp->visible) {
  526.                poof = TRUE;
  527.                top = window->top_line;
  528.                bottom = window->bottom_line;
  529.             } else
  530.                wp = wp->next;
  531.          }
  532.          if (poof == FALSE) {
  533.             /*
  534.              * see if there are any windows above
  535.              */
  536.             wp = g_status.window_list;
  537.             while (wp != NULL && poof == FALSE) {
  538.                if (wp->bottom_line+2 == window->top_line) {
  539.                   poof = TRUE;
  540.                   top = wp->top_line;
  541.                   bottom = window->bottom_line;
  542.                } else
  543.                   wp = wp->next;
  544.             }
  545.          }
  546.          if (poof == FALSE) {
  547.             /*
  548.              * see if there are any windows below
  549.              */
  550.             wp = g_status.window_list;
  551.             while (wp != NULL && poof == FALSE) {
  552.                if (wp->top_line-2 == window->bottom_line) {
  553.                   poof = TRUE;
  554.                   top = window->top_line;
  555.                   bottom = wp->bottom_line;
  556.                } else
  557.                   wp = wp->next;
  558.             }
  559.             if (wp == NULL)
  560.                wp = g_status.window_list;
  561.          }
  562.       }
  563.       wp->visible = TRUE;
  564.       cline = wp->cline - wp->top_line;
  565.       wp->top_line = top;
  566.       wp->bottom_line = bottom;
  567.       wp->cline = wp->top_line + cline;
  568.       if (wp->cline > wp->bottom_line)
  569.          wp->cline = wp->top_line;
  570.       setup_window( wp );
  571.       show_window_header( wp->file_info->file_name, wp );
  572.       show_size_name( wp );
  573.       show_size( wp );
  574.       show_line_col( wp );
  575.  
  576.       /*
  577.        * The window above, below, or previously invisible becomes the new
  578.        * current window.
  579.        */
  580.       g_status.current_window = wp;
  581.  
  582.       /*
  583.        * free unused file memory if necessary
  584.        */
  585.       file = window->file_info;
  586.       if (--file->ref_count == 0) {
  587.          /*
  588.           * no window now refers to this file, so remove file from the list
  589.           */
  590.          if (file->prev == NULL)
  591.             g_status.file_list = file->next;
  592.          else
  593.             file->prev->next = file->next;
  594.          if (file->next)
  595.             file->next->prev = file->prev;
  596.  
  597.          /*
  598.           * close up the gap in the memory buffer
  599.           */
  600.          number = ptoul( g_status.end_mem ) - ptoul( file->end_text );
  601.          hw_move( file->start_text, file->end_text, number );
  602.          number = ptoul( file->end_text ) - ptoul( file->start_text );
  603.          g_status.end_mem = addltop( -number, g_status.end_mem );
  604.          adjust_windows_cursor( window, -number, 0 );
  605.          adjust_start_end( file, -number );
  606.          show_avail_mem( );
  607.  
  608.          /*
  609.           * free the memory taken by the file structure
  610.           */
  611.          free( file );
  612.          --g_status.file_count;
  613.          show_file_count( g_status.file_count );
  614.       }
  615.  
  616.       /*
  617.        * free the memory taken by the window structure
  618.        */
  619.       free( window );
  620.       g_status.current_file = wp->file_info;
  621.       wp->dirty = LOCAL;
  622.    }
  623. }
  624.  
  625.  
  626. /*
  627.  * Name:    create_window
  628.  * Purpose: To allocate space for a new window structure, and set up some
  629.  *           of the relevant fields.
  630.  * Date:    June 5, 1991
  631.  * Passed:  window: pointer to window pointer
  632.  *          top:    the top line of the new window
  633.  *          bottom: the bottom line of the new window
  634.  *          file:   the file structure to be associated with the new window
  635.  * Returns: OK if window could be created
  636.  *          ERROR if out of memory
  637.  */
  638. int  create_window( window, top, bottom, file )
  639. windows **window;  /* the new window structure */
  640. int top;
  641. int bottom;
  642. file_infos *file;
  643. {
  644. windows *wp;      /* temporary variable - use it instead of **window */
  645. windows *prev;
  646. int rc;           /* return code */
  647.  
  648.    rc = OK;
  649.    /*
  650.     * allocate space for new window structure
  651.     */
  652.    if ((*window = (windows *)calloc( 1, sizeof(windows) )) == NULL) {
  653.       error( WARNING, g_display.nlines, "out of memory for window" );
  654.       rc = ERROR;
  655.    } else {
  656.  
  657.      /*
  658.       * set up appropriate fields
  659.       */
  660.       wp = *window;
  661.       wp->file_info = file;
  662.       wp->cline = wp->top_line = top+1;
  663.       wp->bottom_line = bottom;
  664.       wp->prev = NULL;
  665.       wp->next = NULL;
  666.       wp->dirty = LOCAL;
  667.       setup_window( wp );
  668.  
  669.       /*
  670.        * add window into window list
  671.        */
  672.       prev = g_status.current_window;
  673.       if (prev) {
  674.          (*window)->prev = prev;
  675.          if (prev->next)
  676.             prev->next->prev = *window;
  677.          (*window)->next = prev->next;
  678.          prev->next = *window;
  679.       }
  680.       if (g_status.window_list == NULL)
  681.          g_status.window_list = *window;
  682.  
  683.       /*
  684.        * record that another window is referencing this file
  685.        */
  686.       ++file->ref_count;
  687.    }
  688.    return( rc );
  689. }
  690.  
  691. /*
  692.  * Name:    edit_file
  693.  * Purpose: To allocate space for a new file structure, and set up some
  694.  *           of the relevant fields.
  695.  * Date:    June 5, 1991
  696.  * Passed:  name:  name of the file to edit
  697.  * Returns: OK if file structure could be created
  698.  *          ERROR if out of memory
  699.  */
  700. int  edit_file( name )
  701. char *name;
  702. {
  703. int rc;           /* return code */
  704. int existing;
  705. int line;
  706. file_infos *file;   /* file structure for file belonging to new window */
  707. file_infos *fp;
  708. text_ptr next;      /* text pointer */
  709. long size;
  710. struct stat filestat;  /* struct stat defined in \sys\stat */
  711. char buff[MAX_COLS+2];
  712.  
  713.    rc = OK;
  714.    line = g_display.nlines;
  715.    if (hw_fattrib( name ) != ERROR) {
  716.       existing = TRUE;
  717.       /*
  718.        * g_status.temp_end is set last character read in file
  719.        */
  720.       if (load_file( name ) != OK)
  721.          rc = ERROR;
  722.    } else {
  723.       /*
  724.        * setup as empty file
  725.        */
  726.       existing = FALSE;
  727.       g_status.temp_end = g_status.end_mem;
  728.    }
  729.  
  730.    if (rc != ERROR) {
  731.       /*
  732.        * allocate a file structure for the new file
  733.        */
  734.       file = (file_infos *)calloc( 1, sizeof(file_infos) );
  735.       if (file == NULL) {
  736.          error( WARNING, g_display.nlines, "out of memory for file info" );
  737.          rc = ERROR;
  738.       } else {
  739.          /*
  740.           * add file into list
  741.           */
  742.          file->prev = NULL;
  743.          file->next = NULL;
  744.          if (g_status.file_list == NULL)
  745.             g_status.file_list = file;
  746.          else {
  747.             fp = g_status.current_file;
  748.             file->prev = fp;
  749.             if (fp->next)
  750.                fp->next->prev = file;
  751.             file->next = fp->next;
  752.             fp->next = file;
  753.          }
  754.       }
  755.       if (rc != ERROR) {
  756.          /*
  757.           * set up all the info we need to know about a file, and
  758.           *  record that we have used some more memory.
  759.           */
  760.          strcpy( file->file_name, name );
  761.          stat( name, &filestat );
  762.          file->file_attrib = filestat.st_mode;
  763.          file->start_text = g_status.end_mem;
  764.          *g_status.temp_end = CONTROL_Z;
  765.          g_status.temp_end = cpf( g_status.temp_end );
  766.          g_status.end_mem = g_status.temp_end + 1;
  767.          g_status.temp_end = g_status.end_mem;
  768.          file->end_text = g_status.end_mem;
  769.          size = 0l;
  770.          if (existing) {
  771.             next = file->start_text = cpf( file->start_text );
  772.             while ((next = find_next( next )) != NULL)
  773.                size++;
  774.          }
  775.          file->length      = size;
  776.          file->block_end   = file->block_start = NULL;
  777.          file->block_bc    = file->block_ec = 0;
  778.          file->block_br    = file->block_er = 0l;
  779.          file->block_type  = NOTMARKED;
  780.          file->modified    = FALSE;
  781.       }
  782.    }
  783.    if (rc == OK && !existing)
  784.       file->new_file = TRUE;
  785.    else if (rc == OK && existing)
  786.       file->new_file = FALSE;
  787.    if (rc != ERROR) {
  788.       g_status.current_file = file;
  789.       file->ref_count = 0;
  790.       ++g_status.file_count;
  791.       show_avail_mem( );
  792.    }
  793.    return( rc );
  794. }
  795.  
  796.  
  797. /*
  798.  * Name:    edit_another_file
  799.  * Purpose: Bring in another file to editor.
  800.  * Date:    June 5, 1991
  801.  * Passed:  window: information allowing access to the current window
  802.  * Notes:   New window replaces old window.  Old window becomes invisible.
  803.  */
  804. void edit_another_file( window )
  805. windows *window;
  806. {
  807. char name[MAX_COLS];              /* new name for file */
  808. int prompt_line;
  809. int ok;
  810.  
  811.    /*
  812.     * read in name, no default
  813.     */
  814.    prompt_line = window->bottom_line;
  815.    name[0] = '\0';
  816.    if (get_name( "File to edit: ", prompt_line, name,
  817.                  g_display.message_color ) == OK) {
  818.       ok = edit_file( name );
  819.       if (ok != ERROR) {
  820.          ok = initialize_window( );
  821.          if (ok != ERROR) {
  822.             window = g_status.current_window;
  823.             show_window_header( window->file_info->file_name, window );
  824.             show_size_name( window );
  825.             show_size( window );
  826.             show_file_count( g_status.file_count );
  827.             window->dirty = LOCAL;
  828.          }
  829.       }
  830.    }
  831. }
  832.